package com.guardchina.framework.util.model;

import com.guardchina.framework.util.constant.ResultStatus;
import com.google.gson.Gson;
import com.guardchina.framework.util.exception.BusinessException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;

/**
 * 描述：返回结构定义
 *
 * @author lwb
 * @date 2019/3/15 14:24
 */
@Data
@Slf4j
public class ResultHolder<T> implements Serializable {

    private static final long serialVersionUID = 1L;
    public static final String SUCCESS_MESSAGE = "操作成功";
    public static final String FAILURE_MESSAGE = "操作失败";

    /**
     * 返回码
     */
    private Integer code;

    /**
     * 描述信息
     */
    private String message;

    /**
     * 附加信息
     */
    private String extra;


    /**
     * 返回内容
     */
    private T data;

    /**
     * 服务器时间戳
     */
    private Long timestamp;


    public ResultHolder(){

    }


    public ResultHolder(Integer code, String message, T data, String extra){
        this.code = code;
        this.message = message;
        this.data = data;
        this.extra = extra;
        this.timestamp = System.currentTimeMillis();
        if(code != 0){
            log.error("Result error[{}]：{},{}",code, message, extra);
        }else{
            log.trace("Result body：{}", new Gson().toJson(data));
        }
    }

    public static <T> ResultHolder<T> success(){
        return  ResultHolder.success(null);
    }

    public static <T> ResultHolder<T> success(T body){
        return new ResultHolder<>(ResultStatus.SUCCESS, SUCCESS_MESSAGE, body, null);
    }

    public static <T> ResultHolder<T> error(int errorCode){
        return error(errorCode, FAILURE_MESSAGE);
    }

    public static <T> ResultHolder<T> error(int error, String message){
        return error(error, message, null);
    }

    public static <T> ResultHolder<T> error(int errorCode, String message, String extra){
       return error(errorCode, null, message, extra);
    }

    public static <T> ResultHolder<T> error(int errorCode, T data, String message, String extra){
        return new ResultHolder<>(errorCode, message, data, extra);
    }

    public static boolean isSuccess(ResultHolder resultHolder){
        return ResultStatus.SUCCESS.equals(resultHolder.getCode());
    }

    public T checkBody(){
        if(!ResultHolder.isSuccess(this)){
            throw new BusinessException(message);
        }

        return data;
    }

}
